package eg.ci.mvn.service.core.config.log4j2;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.util.Strings;

/**
 * filter log by thread name and log level
 *
 * @author Keven
 * @version 1.0
 * date: 2020-02-26
 */
//声明插件的类型，名字等信息
@Plugin(name = "ThreadFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
public class ThreadFilter extends AbstractFilter {

    private String threadName;
    private Result onMatch;
    private Result onMisMatch;
    private Level level;

    public ThreadFilter(String threadName, Result onMatch, Result onMisMatch, Level level) {
        super();
        this.threadName = threadName;
        this.onMatch = onMatch;
        this.onMisMatch = onMisMatch;
        this.level = level;
    }

    /**
     * Create a ThreadFilter instance.
     *
     * @param threadName The thread name
     * @param match      The action to take on a match.
     * @param mismatch   The action to take on a mismatch.
     * @param level      log level
     * @return The created MyCustomFilter.
     */
    //@PluginFactory注解对应的必须使用一个静态的方法，传入的参数用@PluginAttribute修饰
    @PluginFactory
    public static ThreadFilter createFilter(@PluginAttribute("threadName") final String threadName,
                                            @PluginAttribute("onMatch") final Result match,
                                            @PluginAttribute("onMismatch") final Result mismatch,
                                            @PluginAttribute("level") final Level level) {
        assert Strings.isNotBlank(threadName);
        final Result onMatch = match == null ? Result.NEUTRAL : match;
        final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
        return new ThreadFilter(threadName, onMatch, onMismatch, level);
    }

    @Override
    public Result filter(LogEvent event) {
        //你的业务逻辑，这里是根据线程前缀名，以及日志等级来过滤
        if (event.getLevel().name().equals(this.level.name()) && event.getThreadName().startsWith(threadName)) {
            return this.onMatch;
        }
        return this.onMisMatch;
    }

    @Override
    public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
        return super.filter(logger, level, marker, msg, t);
    }
}